package com.vinxin.app.exception

import cn.hutool.log.Log
import cn.hutool.log.LogFactory
import com.vinxin.app.model.ResponseModel
import feign.codec.DecodeException
import jakarta.servlet.http.HttpServletRequest
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.RestControllerAdvice
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler

@RestControllerAdvice
class GlobalExceptionHandler : ResponseEntityExceptionHandler() {
    private val log: Log = LogFactory.get()

    @ExceptionHandler(NullPointerException::class)
    fun handleException(e: NullPointerException, r: HttpServletRequest): ResponseModel<String?> {
        log.error(e, "request url is '{}', facing null pointer exception.", r.requestURL)
        return ResponseModel.error(ResponseCodeEnum.NULL_POINTER_EXCEPTION, e.stackTrace.first().toString())
    }

    @ExceptionHandler(VXException::class)
    fun handleException(e: VXException, r: HttpServletRequest): ResponseModel<String?> {
        log.error(e, "request url is '{}', facing vin-xin application exception.", r.requestURL)
        return ResponseModel.error(e.responseCodeEnum, e.message)
    }

    @ExceptionHandler(Exception::class, DecodeException::class)
    fun handleException(e: Exception, r: HttpServletRequest): ResponseModel<String?> {
        if (e.cause is VXException) return handleException(e.cause as VXException, r)
        log.error(e, "request url is '{}', facing internal server exception.", r.requestURL)
        return ResponseModel.error(ResponseCodeEnum.INTERNAL_SERVER_ERROR, e.message)
    }
}